'use client';

import { observer } from 'mobx-react-lite';
import { useParams } from 'next/navigation';
import { useRouter } from 'next/navigation';
import { useEffect } from 'react';
import { useInView } from 'react-intersection-observer';

import { useStores } from '@/app/(root)/AppProviders';
import OutlineButton from '@/components/button/OutlineButton';
import SongList from '@/components/song/Songlist';
import TitleText from '@/components/title/TitleText';
import usePageViewLog from '@/hooks/usePageViewLog';
import { components } from '@/lib/gen';
import { ContextType } from '@/logging/contextTypes';

import { Clip } from '../../../../state/clipStore';
import SortingMenu from '../../search/SortingMenu';

export type SearchRankingEnum = components['schemas']['SearchRankingEnum'];

const RECOMMEND_STYLE_NUM = 20;
const DEFAULT_TAG_CONTEXT_ID = 'NO_VALID_TAG';

const TagPage = observer(() => {
  const params = useParams<{ slug: string }>();
  const { clips, tag, genForm } = useStores();
  const router = useRouter();

  let styleTag = '';
  let rankBy = '';
  tag.tagTerm = params.slug;
  // TODO: replace this with createV2.getRecommendedStyles
  useEffect(() => {
    genForm.initStyles();
  }, []);

  usePageViewLog({
    actionName: 'PageViewed',
    componentContext: 'style',
    principalObjectType: 'style',
    principalObjectValue: params.slug,
  });

  useEffect(() => {
    // dedup search query
    if (styleTag == tag.tagTerm && rankBy == tag.rankBy) {
      return;
    }
    styleTag = tag.tagTerm;
    rankBy = tag.rankBy;
    tag.clips = [];
    const searchingClips = async () => {
      await tag.tagSearch(tag.tagTerm, false);
    };
    searchingClips();
  }, [tag.tagTerm, tag.rankBy]);

  useEffect(() => {
    clips.updateClips(tag.clips);
  }, [tag.clips]);

  const { ref: spinnerRef } = useInView({
    threshold: 0,
    onChange: async (inView) => {
      if (inView && tag.clips.length > 0) {
        const searchingClips = async () => {
          await tag.tagSearch(tag.tagTerm, true);
          clips.updateClips(tag.clips);
        };
        searchingClips();
      }
    },
  });

  return (
    <>
      <div className='mt-6 ml-6 flex w-full flex-col lg:w-[calc(100%-24px)]'>
        <div className='mb-2'>
          <TitleText
            text={decodeURIComponent(
              tag.tagTerm.charAt(0).toUpperCase() + tag.tagTerm.slice(1)
            )}
          />
        </div>
        <div className='mt-2 mr-2 mb-2 flex items-start justify-start md:mt-5 md:mr-5 md:mb-5'>
          <div className='flex w-full justify-between'>
            <div
              className='flex max-w-[800px] flex-1 flex-nowrap overflow-x-scroll overflow-y-hidden pb-2'
              style={{ scrollbarWidth: 'none' }}
            >
              {tag.clips &&
                tag.clips.length > 0 &&
                // TODO: replace with createV2.getRecommendedStyles
                genForm
                  .getRandomDefaultStyles(RECOMMEND_STYLE_NUM)
                  .map((style) => (
                    <OutlineButton
                      onClick={() => router.push(`/style/${style}`)}
                      key={style}
                      hasText
                    >
                      {style}
                    </OutlineButton>
                  ))}
            </div>
            <div className='mr-4 ml-5 w-[140px]'>
              <SortingMenu
                onSwitchSorting={(selectionText) => {
                  tag.rankBy = selectionText as SearchRankingEnum;
                }}
              />
            </div>
          </div>
        </div>
        <SongList
          songs={tag.clips as Clip[]}
          infiniteScrollLoadingRef={spinnerRef}
          playlistId={tag.tagTerm || DEFAULT_TAG_CONTEXT_ID}
          contextId={tag.tagTerm || DEFAULT_TAG_CONTEXT_ID}
          contextType={ContextType.StyleTag}
          isLoading={false}
          useNewSongRow
          showPreview={false}
        />
      </div>
    </>
  );
});

export default TagPage;
